/*
 * Album.h
 *
 *  Created on: Jun 22, 2013
 *      Author: amatzlia
 */

#ifndef ALBUM_H_
#define ALBUM_H_

#include <iostream>
#include "list.h"
using std::string;

/**
 * A class used to represent an album in a record store, holding the details:
 * barcode, price, year, number of purchases, title and artist.
 */
class Album {
public:
	/**
	 * Creates a new album with given barcode, price, year, numPurchased, title
	 * and artist.
	 * If given barcode <= 0 then mtm::IVALID_BARCODE exception is thrown.
	 * If given price <= 0 then mtm::IVALID_PRICE exception is thrown.
	 * If given numPurchased < 0 then mtm::INVALID_NUM_PURCHASED exception is
	 *  thrown.
	 */
	Album(int barcode, int price, int year, int numPurchased, string title,
			string artist);

	/**
	 * Creates a new album with given barcode.
	 * For use as a search dummy object.
	 * If given barcode <= 0 then mtm::IVALID_BARCODE exception is thrown.
	 */
	explicit Album(int barcode);

	/**
	 * Creates a new album.
	 * For use of Album as a list item.
	 */
	Album();

	/**
	 * @return a string representing a minimal album description.
	 */
	string getMinimalString() const;

	/**
	 * @return a string representing a full album description.
	 */
	string getFullString() const;

	/**
	 * Increases the album's number of purchases.
	 * @return the price of the album.
	 */
	int purchase();

	/**
	 * A function object used to sort Album objects by barcode (ascending)
	 * and to find them by barcode, in a set of Albums.
	 */
	class SortByBarcode;

	/**
	 * A function object used to find Album objects by barcode in a List.
	 */
	class BarcodeEquals;

	/**
	 * A function object used to sort Album objects in a set
	 * by numPurchased (descending) and then by id (ascending).
	 */
	class SortByNumPurchasedThenBarcode;

private:
	int barcode;
	int price;
	int year;
	int numPurchased;
	string title;
	string artist;
};

class Album::SortByBarcode {
public:
	bool operator()(const Album& albumA, const Album& albumB) const;
};

class Album::BarcodeEquals {
	int barcode;
public:
	explicit BarcodeEquals(const Album& album);
	bool operator()(const Album& album) const;
};

class Album::SortByNumPurchasedThenBarcode {
public:
	bool operator()(const Album& albumA, const Album& albumB) const;
};

/**
 * Implements comparison between two albums, using barcode.
 * @return true if barcodes of given albums are equal, false otherwise.
 */
bool operator==(const Album& albumA, const Album& albumB);

#endif /* ALBUM_H_ */
